1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.base;
18
19 import static com.google.common.base.CharMatcher.WHITESPACE;
20 import static com.google.common.collect.Lists.newArrayList;
21
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.collect.ImmutableSet;
24 import com.google.common.testing.EqualsTester;
25
26 import junit.framework.AssertionFailedError;
27 import junit.framework.TestCase;
28
29 import java.io.Serializable;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Iterator;
35 import java.util.List;
36
37
38
39
40
41
42 @GwtCompatible(emulated = true)
43 public class PredicatesTest extends TestCase {
44 private static final Predicate<Integer> TRUE = Predicates.alwaysTrue();
45 private static final Predicate<Integer> FALSE = Predicates.alwaysFalse();
46 private static final Predicate<Integer> NEVER_REACHED =
47 new Predicate<Integer>() {
48 @Override
49 public boolean apply(Integer i) {
50 throw new AssertionFailedError(
51 "This predicate should never have been evaluated");
52 }
53 };
54
55
56 static class IsOdd implements Predicate<Integer>, Serializable {
57 private static final long serialVersionUID = 0x150ddL;
58 @Override
59 public boolean apply(Integer i) {
60 return (i.intValue() & 1) == 1;
61 }
62 @Override public int hashCode() {
63 return 0x150dd;
64 }
65 @Override public boolean equals(Object obj) {
66 return obj instanceof IsOdd;
67 }
68 @Override public String toString() {
69 return "IsOdd";
70 }
71 }
72
73
74
75
76
77
78
79 private static IsOdd isOdd() {
80 return new IsOdd();
81 }
82
83
84
85
86
87 public void testAlwaysTrue_apply() {
88 assertEvalsToTrue(Predicates.alwaysTrue());
89 }
90
91 public void testAlwaysTrue_equality() throws Exception {
92 new EqualsTester()
93 .addEqualityGroup(TRUE, Predicates.alwaysTrue())
94 .addEqualityGroup(isOdd())
95 .addEqualityGroup(Predicates.alwaysFalse())
96 .testEquals();
97 }
98
99
100
101
102
103 public void testAlwaysFalse_apply() throws Exception {
104 assertEvalsToFalse(Predicates.alwaysFalse());
105 }
106
107 public void testAlwaysFalse_equality() throws Exception {
108 new EqualsTester()
109 .addEqualityGroup(FALSE, Predicates.alwaysFalse())
110 .addEqualityGroup(isOdd())
111 .addEqualityGroup(Predicates.alwaysTrue())
112 .testEquals();
113 }
114
115
116
117
118
119 public void testNot_apply() {
120 assertEvalsToTrue(Predicates.not(FALSE));
121 assertEvalsToFalse(Predicates.not(TRUE));
122 assertEvalsLikeOdd(Predicates.not(Predicates.not(isOdd())));
123 }
124
125 public void testNot_equality() {
126 new EqualsTester()
127 .addEqualityGroup(Predicates.not(isOdd()), Predicates.not(isOdd()))
128 .addEqualityGroup(Predicates.not(TRUE))
129 .addEqualityGroup(isOdd())
130 .testEquals();
131 }
132
133 public void testNot_equalityForNotOfKnownValues() {
134 new EqualsTester()
135 .addEqualityGroup(TRUE, Predicates.alwaysTrue())
136 .addEqualityGroup(FALSE)
137 .addEqualityGroup(Predicates.not(TRUE))
138 .testEquals();
139
140 new EqualsTester()
141 .addEqualityGroup(FALSE, Predicates.alwaysFalse())
142 .addEqualityGroup(TRUE)
143 .addEqualityGroup(Predicates.not(FALSE))
144 .testEquals();
145
146 new EqualsTester()
147 .addEqualityGroup(Predicates.isNull(), Predicates.isNull())
148 .addEqualityGroup(Predicates.notNull())
149 .addEqualityGroup(Predicates.not(Predicates.isNull()))
150 .testEquals();
151
152 new EqualsTester()
153 .addEqualityGroup(Predicates.notNull(), Predicates.notNull())
154 .addEqualityGroup(Predicates.isNull())
155 .addEqualityGroup(Predicates.not(Predicates.notNull()))
156 .testEquals();
157 }
158
159
160
161
162
163 @SuppressWarnings("unchecked")
164 public void testAnd_applyNoArgs() {
165 assertEvalsToTrue(Predicates.and());
166 }
167
168 @SuppressWarnings("unchecked")
169 public void testAnd_equalityNoArgs() {
170 new EqualsTester()
171 .addEqualityGroup(Predicates.and(), Predicates.and())
172 .addEqualityGroup(Predicates.and(FALSE))
173 .addEqualityGroup(Predicates.or())
174 .testEquals();
175 }
176
177 @SuppressWarnings("unchecked")
178 public void testAnd_applyOneArg() {
179 assertEvalsLikeOdd(Predicates.and(isOdd()));
180 }
181
182 @SuppressWarnings("unchecked")
183 public void testAnd_equalityOneArg() {
184 Object[] notEqualObjects = {Predicates.and(NEVER_REACHED, FALSE)};
185 new EqualsTester()
186 .addEqualityGroup(
187 Predicates.and(NEVER_REACHED), Predicates.and(NEVER_REACHED))
188 .addEqualityGroup(notEqualObjects)
189 .addEqualityGroup(Predicates.and(isOdd()))
190 .addEqualityGroup(Predicates.and())
191 .addEqualityGroup(Predicates.or(NEVER_REACHED))
192 .testEquals();
193 }
194
195 public void testAnd_applyBinary() {
196 assertEvalsLikeOdd(Predicates.and(isOdd(), TRUE));
197 assertEvalsLikeOdd(Predicates.and(TRUE, isOdd()));
198 assertEvalsToFalse(Predicates.and(FALSE, NEVER_REACHED));
199 }
200
201 @SuppressWarnings("unchecked")
202 public void testAnd_equalityBinary() {
203 new EqualsTester()
204 .addEqualityGroup(
205 Predicates.and(TRUE, NEVER_REACHED),
206 Predicates.and(TRUE, NEVER_REACHED))
207 .addEqualityGroup(Predicates.and(NEVER_REACHED, TRUE))
208 .addEqualityGroup(Predicates.and(TRUE))
209 .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
210 .testEquals();
211 }
212
213 @SuppressWarnings("unchecked")
214 public void testAnd_applyTernary() {
215 assertEvalsLikeOdd(Predicates.and(isOdd(), TRUE, TRUE));
216 assertEvalsLikeOdd(Predicates.and(TRUE, isOdd(), TRUE));
217 assertEvalsLikeOdd(Predicates.and(TRUE, TRUE, isOdd()));
218 assertEvalsToFalse(Predicates.and(TRUE, FALSE, NEVER_REACHED));
219 }
220
221 @SuppressWarnings("unchecked")
222 public void testAnd_equalityTernary() {
223 new EqualsTester()
224 .addEqualityGroup(
225 Predicates.and(TRUE, isOdd(), NEVER_REACHED),
226 Predicates.and(TRUE, isOdd(), NEVER_REACHED))
227 .addEqualityGroup(Predicates.and(isOdd(), NEVER_REACHED, TRUE))
228 .addEqualityGroup(Predicates.and(TRUE))
229 .addEqualityGroup(Predicates.or(TRUE, isOdd(), NEVER_REACHED))
230 .testEquals();
231 }
232
233 @SuppressWarnings("unchecked")
234 public void testAnd_applyIterable() {
235 Collection<Predicate<Integer>> empty = Arrays.asList();
236 assertEvalsToTrue(Predicates.and(empty));
237 assertEvalsLikeOdd(Predicates.and(Arrays.asList(isOdd())));
238 assertEvalsLikeOdd(Predicates.and(Arrays.asList(TRUE, isOdd())));
239 assertEvalsToFalse(Predicates.and(Arrays.asList(FALSE, NEVER_REACHED)));
240 }
241
242 @SuppressWarnings("unchecked")
243 public void testAnd_equalityIterable() {
244 new EqualsTester()
245 .addEqualityGroup(
246 Predicates.and(Arrays.asList(TRUE, NEVER_REACHED)),
247 Predicates.and(Arrays.asList(TRUE, NEVER_REACHED)),
248 Predicates.and(TRUE, NEVER_REACHED))
249 .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
250 .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
251 .testEquals();
252 }
253
254 @SuppressWarnings("unchecked")
255 public void testAnd_arrayDefensivelyCopied() {
256 Predicate[] array = {Predicates.alwaysFalse()};
257 Predicate<Object> predicate = Predicates.and(array);
258 assertFalse(predicate.apply(1));
259 array[0] = Predicates.alwaysTrue();
260 assertFalse(predicate.apply(1));
261 }
262
263 public void testAnd_listDefensivelyCopied() {
264 List<Predicate<Object>> list = newArrayList();
265 Predicate<Object> predicate = Predicates.and(list);
266 assertTrue(predicate.apply(1));
267 list.add(Predicates.alwaysFalse());
268 assertTrue(predicate.apply(1));
269 }
270
271 public void testAnd_iterableDefensivelyCopied() {
272 final List<Predicate<Object>> list = newArrayList();
273 Iterable<Predicate<Object>> iterable = new Iterable<Predicate<Object>>() {
274 @Override
275 public Iterator<Predicate<Object>> iterator() {
276 return list.iterator();
277 }
278 };
279 Predicate<Object> predicate = Predicates.and(iterable);
280 assertTrue(predicate.apply(1));
281 list.add(Predicates.alwaysFalse());
282 assertTrue(predicate.apply(1));
283 }
284
285
286
287
288
289 @SuppressWarnings("unchecked")
290 public void testOr_applyNoArgs() {
291 assertEvalsToFalse(Predicates.or());
292 }
293
294 @SuppressWarnings("unchecked")
295 public void testOr_equalityNoArgs() {
296 new EqualsTester()
297 .addEqualityGroup(Predicates.or(), Predicates.or())
298 .addEqualityGroup(Predicates.or(TRUE))
299 .addEqualityGroup(Predicates.and())
300 .testEquals();
301 }
302
303 @SuppressWarnings("unchecked")
304 public void testOr_applyOneArg() {
305 assertEvalsToTrue(Predicates.or(TRUE));
306 assertEvalsToFalse(Predicates.or(FALSE));
307 }
308
309 @SuppressWarnings("unchecked")
310 public void testOr_equalityOneArg() {
311 new EqualsTester()
312 .addEqualityGroup(
313 Predicates.or(NEVER_REACHED), Predicates.or(NEVER_REACHED))
314 .addEqualityGroup(Predicates.or(NEVER_REACHED, TRUE))
315 .addEqualityGroup(Predicates.or(TRUE))
316 .addEqualityGroup(Predicates.or())
317 .addEqualityGroup(Predicates.and(NEVER_REACHED))
318 .testEquals();
319 }
320
321 public void testOr_applyBinary() {
322 Predicate<Integer> falseOrFalse = Predicates.or(FALSE, FALSE);
323 Predicate<Integer> falseOrTrue = Predicates.or(FALSE, TRUE);
324 Predicate<Integer> trueOrAnything = Predicates.or(TRUE, NEVER_REACHED);
325
326 assertEvalsToFalse(falseOrFalse);
327 assertEvalsToTrue(falseOrTrue);
328 assertEvalsToTrue(trueOrAnything);
329 }
330
331 @SuppressWarnings("unchecked")
332 public void testOr_equalityBinary() {
333 new EqualsTester()
334 .addEqualityGroup(
335 Predicates.or(FALSE, NEVER_REACHED),
336 Predicates.or(FALSE, NEVER_REACHED))
337 .addEqualityGroup(Predicates.or(NEVER_REACHED, FALSE))
338 .addEqualityGroup(Predicates.or(TRUE))
339 .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
340 .testEquals();
341 }
342
343 @SuppressWarnings("unchecked")
344 public void testOr_applyTernary() {
345 assertEvalsLikeOdd(Predicates.or(isOdd(), FALSE, FALSE));
346 assertEvalsLikeOdd(Predicates.or(FALSE, isOdd(), FALSE));
347 assertEvalsLikeOdd(Predicates.or(FALSE, FALSE, isOdd()));
348 assertEvalsToTrue(Predicates.or(FALSE, TRUE, NEVER_REACHED));
349 }
350
351 @SuppressWarnings("unchecked")
352 public void testOr_equalityTernary() {
353 new EqualsTester()
354 .addEqualityGroup(
355 Predicates.or(FALSE, NEVER_REACHED, TRUE),
356 Predicates.or(FALSE, NEVER_REACHED, TRUE))
357 .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED, FALSE))
358 .addEqualityGroup(Predicates.or(TRUE))
359 .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED, TRUE))
360 .testEquals();
361 }
362
363 @SuppressWarnings("unchecked")
364 public void testOr_applyIterable() {
365 Predicate<Integer> vacuouslyFalse =
366 Predicates.or(Collections.<Predicate<Integer>>emptyList());
367 Predicate<Integer> troo = Predicates.or(Collections.singletonList(TRUE));
368
369
370
371
372 Predicate<Integer> trueAndFalse = Predicates.or(Arrays.asList(TRUE, FALSE));
373
374 assertEvalsToFalse(vacuouslyFalse);
375 assertEvalsToTrue(troo);
376 assertEvalsToTrue(trueAndFalse);
377 }
378
379 @SuppressWarnings("unchecked")
380 public void testOr_equalityIterable() {
381 new EqualsTester()
382 .addEqualityGroup(
383 Predicates.or(Arrays.asList(FALSE, NEVER_REACHED)),
384 Predicates.or(Arrays.asList(FALSE, NEVER_REACHED)),
385 Predicates.or(FALSE, NEVER_REACHED))
386 .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
387 .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
388 .testEquals();
389 }
390
391 @SuppressWarnings("unchecked")
392 public void testOr_arrayDefensivelyCopied() {
393 Predicate[] array = {Predicates.alwaysFalse()};
394 Predicate<Object> predicate = Predicates.or(array);
395 assertFalse(predicate.apply(1));
396 array[0] = Predicates.alwaysTrue();
397 assertFalse(predicate.apply(1));
398 }
399
400 public void testOr_listDefensivelyCopied() {
401 List<Predicate<Object>> list = newArrayList();
402 Predicate<Object> predicate = Predicates.or(list);
403 assertFalse(predicate.apply(1));
404 list.add(Predicates.alwaysTrue());
405 assertFalse(predicate.apply(1));
406 }
407
408 public void testOr_iterableDefensivelyCopied() {
409 final List<Predicate<Object>> list = newArrayList();
410 Iterable<Predicate<Object>> iterable = new Iterable<Predicate<Object>>() {
411 @Override
412 public Iterator<Predicate<Object>> iterator() {
413 return list.iterator();
414 }
415 };
416 Predicate<Object> predicate = Predicates.or(iterable);
417 assertFalse(predicate.apply(1));
418 list.add(Predicates.alwaysTrue());
419 assertFalse(predicate.apply(1));
420 }
421
422
423
424
425
426 public void testIsEqualTo_apply() {
427 Predicate<Integer> isOne = Predicates.equalTo(1);
428
429 assertTrue(isOne.apply(1));
430 assertFalse(isOne.apply(2));
431 assertFalse(isOne.apply(null));
432 }
433
434 public void testIsEqualTo_equality() {
435 new EqualsTester()
436 .addEqualityGroup(Predicates.equalTo(1), Predicates.equalTo(1))
437 .addEqualityGroup(Predicates.equalTo(2))
438 .addEqualityGroup(Predicates.equalTo(null))
439 .testEquals();
440 }
441
442 public void testIsEqualToNull_apply() {
443 Predicate<Integer> isNull = Predicates.equalTo(null);
444 assertTrue(isNull.apply(null));
445 assertFalse(isNull.apply(1));
446 }
447
448 public void testIsEqualToNull_equality() {
449 new EqualsTester()
450 .addEqualityGroup(Predicates.equalTo(null), Predicates.equalTo(null))
451 .addEqualityGroup(Predicates.equalTo(1))
452 .addEqualityGroup(Predicates.equalTo("null"))
453 .testEquals();
454 }
455
456
457
458
459
460 public void testIsNull_apply() {
461 Predicate<Integer> isNull = Predicates.isNull();
462 assertTrue(isNull.apply(null));
463 assertFalse(isNull.apply(1));
464 }
465
466 public void testIsNull_equality() {
467 new EqualsTester()
468 .addEqualityGroup(Predicates.isNull(), Predicates.isNull())
469 .addEqualityGroup(Predicates.notNull())
470 .testEquals();
471 }
472
473 public void testNotNull_apply() {
474 Predicate<Integer> notNull = Predicates.notNull();
475 assertFalse(notNull.apply(null));
476 assertTrue(notNull.apply(1));
477 }
478
479 public void testNotNull_equality() {
480 new EqualsTester()
481 .addEqualityGroup(Predicates.notNull(), Predicates.notNull())
482 .addEqualityGroup(Predicates.isNull())
483 .testEquals();
484 }
485
486 public void testIn_apply() {
487 Collection<Integer> nums = Arrays.asList(1, 5);
488 Predicate<Integer> isOneOrFive = Predicates.in(nums);
489
490 assertTrue(isOneOrFive.apply(1));
491 assertTrue(isOneOrFive.apply(5));
492 assertFalse(isOneOrFive.apply(3));
493 assertFalse(isOneOrFive.apply(null));
494 }
495
496 public void testIn_equality() {
497 Collection<Integer> nums = ImmutableSet.of(1, 5);
498 Collection<Integer> sameOrder = ImmutableSet.of(1, 5);
499 Collection<Integer> differentOrder = ImmutableSet.of(5, 1);
500 Collection<Integer> differentNums = ImmutableSet.of(1, 3, 5);
501
502 new EqualsTester()
503 .addEqualityGroup(Predicates.in(nums), Predicates.in(nums),
504 Predicates.in(sameOrder), Predicates.in(differentOrder))
505 .addEqualityGroup(Predicates.in(differentNums))
506 .testEquals();
507 }
508
509 public void testIn_handlesNullPointerException() {
510 class CollectionThatThrowsNPE<T> extends ArrayList<T> {
511 private static final long serialVersionUID = 1L;
512
513 @Override public boolean contains(Object element) {
514 Preconditions.checkNotNull(element);
515 return super.contains(element);
516 }
517 }
518 Collection<Integer> nums = new CollectionThatThrowsNPE<Integer>();
519 Predicate<Integer> isFalse = Predicates.in(nums);
520 assertFalse(isFalse.apply(null));
521 }
522
523 public void testIn_handlesClassCastException() {
524 class CollectionThatThrowsCCE<T> extends ArrayList<T> {
525 private static final long serialVersionUID = 1L;
526
527 @Override public boolean contains(Object element) {
528 throw new ClassCastException("");
529 }
530 }
531 Collection<Integer> nums = new CollectionThatThrowsCCE<Integer>();
532 nums.add(3);
533 Predicate<Integer> isThree = Predicates.in(nums);
534 assertFalse(isThree.apply(3));
535 }
536
537
538
539
540 @SuppressWarnings("unused")
541 public void testIn_compilesWithExplicitSupertype() {
542 Collection<Number> nums = ImmutableSet.of();
543 Predicate<Number> p1 = Predicates.in(nums);
544 Predicate<Object> p2 = Predicates.<Object>in(nums);
545
546
547
548 }
549
550
551 private enum TrimStringFunction implements Function<String, String> {
552 INSTANCE;
553
554 @Override
555 public String apply(String string) {
556 return WHITESPACE.trimFrom(string);
557 }
558 }
559
560 public void testCompose() {
561 Function<String, String> trim = TrimStringFunction.INSTANCE;
562 Predicate<String> equalsFoo = Predicates.equalTo("Foo");
563 Predicate<String> equalsBar = Predicates.equalTo("Bar");
564 Predicate<String> trimEqualsFoo = Predicates.compose(equalsFoo, trim);
565 Function<String, String> identity = Functions.identity();
566
567 assertTrue(trimEqualsFoo.apply("Foo"));
568 assertTrue(trimEqualsFoo.apply(" Foo "));
569 assertFalse(trimEqualsFoo.apply("Foo-b-que"));
570
571 new EqualsTester()
572 .addEqualityGroup(trimEqualsFoo, Predicates.compose(equalsFoo, trim))
573 .addEqualityGroup(equalsFoo)
574 .addEqualityGroup(trim)
575 .addEqualityGroup(Predicates.compose(equalsFoo, identity))
576 .addEqualityGroup(Predicates.compose(equalsBar, trim))
577 .testEquals();
578 }
579
580 public void assertEqualHashCode(
581 Predicate<? super Integer> expected, Predicate<? super Integer> actual) {
582 assertEquals(actual + " should hash like " + expected, expected.hashCode(), actual.hashCode());
583 }
584
585 public void testHashCodeForBooleanOperations() {
586 Predicate<Integer> p1 = Predicates.isNull();
587 Predicate<Integer> p2 = isOdd();
588
589
590 assertEqualHashCode(
591 Predicates.not(p1),
592 Predicates.not(p1));
593
594 assertEqualHashCode(
595 Predicates.and(p1, p2),
596 Predicates.and(p1, p2));
597
598 assertEqualHashCode(
599 Predicates.or(p1, p2),
600 Predicates.or(p1, p2));
601
602
603
604 assertTrue(Predicates.and(p1, p2).hashCode() != Predicates.or(p1, p2).hashCode());
605 }
606
607 private static void assertEvalsToTrue(Predicate<? super Integer> predicate) {
608 assertTrue(predicate.apply(0));
609 assertTrue(predicate.apply(1));
610 assertTrue(predicate.apply(null));
611 }
612
613 private static void assertEvalsToFalse(Predicate<? super Integer> predicate) {
614 assertFalse(predicate.apply(0));
615 assertFalse(predicate.apply(1));
616 assertFalse(predicate.apply(null));
617 }
618
619 private static void assertEvalsLikeOdd(Predicate<? super Integer> predicate) {
620 assertEvalsLike(isOdd(), predicate);
621 }
622
623 private static void assertEvalsLike(
624 Predicate<? super Integer> expected,
625 Predicate<? super Integer> actual) {
626 assertEvalsLike(expected, actual, 0);
627 assertEvalsLike(expected, actual, 1);
628 assertEvalsLike(expected, actual, null);
629 }
630
631 private static <T> void assertEvalsLike(
632 Predicate<? super T> expected,
633 Predicate<? super T> actual,
634 T input) {
635 Boolean expectedResult = null;
636 RuntimeException expectedRuntimeException = null;
637 try {
638 expectedResult = expected.apply(input);
639 } catch (RuntimeException e) {
640 expectedRuntimeException = e;
641 }
642
643 Boolean actualResult = null;
644 RuntimeException actualRuntimeException = null;
645 try {
646 actualResult = actual.apply(input);
647 } catch (RuntimeException e) {
648 actualRuntimeException = e;
649 }
650
651 assertEquals(expectedResult, actualResult);
652 if (expectedRuntimeException != null) {
653 assertNotNull(actualRuntimeException);
654 assertEquals(
655 expectedRuntimeException.getClass(),
656 actualRuntimeException.getClass());
657 }
658 }
659 }
660